package com.a4studio.android.util;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import org.htmlparser.beans.StringBean;

import android.util.Log;


public class ContentReader {

	private final static String TAG=ContentReader.class.getSimpleName();
	
	private String url;
	
	private String result="";
	
	private List<String> textLines = new ArrayList<String>();
	private List<Double>  factors   = new ArrayList<Double>();
	
	private int totalLines = 0;
	
	private Double upperThreshold = 0.;
	private Double lowerThreshold = 0.;
	private Double avg = 0.;
	
	private int lowerBound;
	private int upperBound;
	
	private final static Double FILTER_FAC = 2.;
	private final static Double THRESH_FAC = 2.;
		
	public ContentReader(String url)
	{
		this.url = url;
	}
	
	public ContentReader()
	{
	}

	
	/**
	 * @param url the url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}

	public String getResult() throws Exception
	{

		preHandle();
		dataFilter();
		calculateRange();
		
		for(int i = lowerBound; i <= upperBound; i++)
		{
			result += textLines.get(i) + "\r\n";
		}
		
		return result;
	}
	
	public void preHandle() throws Exception
	{
	     StringBean sb = new StringBean ();
	     sb.setLinks (false);
	     sb.setReplaceNonBreakingSpaces (true);
	     sb.setCollapse (true);
	     sb.setURL (url); // the HTTP is performed here
	     String s = sb.getStrings ();
	     //System.out.println(s);
	     BufferedReader reader = new BufferedReader(new StringReader(s));	     
	     
	     String line;
	     Double max_count = 0.;
	     int tmp = 0;
	     while((line = reader.readLine()) != null)
	     {
	    	 textLines.add(line);
	    	 tmp = line.length();
	    	 factors.add(new Double(tmp));	    	 
	    	 if(tmp >= max_count)
	    	 {
	    		 max_count = (double)tmp;
	    	 }
	     }
	     
	     totalLines = textLines.size();
	     Log.d(TAG,"max_count:" +max_count+" totalLines:"+totalLines);
	     if(max_count.longValue() == 0 || totalLines < 3)
	     {
	    	 
	    	 throw new Exception("all text lines are empty,invalid web page");
	     }
	     List<Double> next_factors = new ArrayList<Double>();
	     for(int i = 0 ; i < totalLines; i++)
	     {
	    	 Double item = new Double(0.);
	    	 item = factors.get(i)/max_count;
	    	 next_factors.add(item);
	     }
	     factors = next_factors;
	     Log.d(TAG,factors.toString());
	     
	}
	
	 void dataFilter () throws Exception
	 {		 
		 if(totalLines < 3) throw new Exception("text lines are less than 3 lines,invalid");
		 
		 List<Double> next_factors = new ArrayList<Double>();
		 
		 Double item = new Double(0.);	 
		 item = (factors.get(0)*FILTER_FAC + factors.get(1))/(FILTER_FAC+1);
		 next_factors.add(item);
		 
		 
		 for(int i =1 ; i < totalLines -1; i ++)
		 {
			 item = new Double(0.);	
			 item = (factors.get(i-1) + FILTER_FAC*factors.get(i) + factors.get(i+1))/(2+FILTER_FAC);
			 next_factors.add(item);
		 }
		 
		 item = new Double(0.);
		 item = (factors.get(totalLines-2) + FILTER_FAC*factors.get(totalLines-1))/(1+FILTER_FAC);
		 next_factors.add(item);
		 
		 factors = next_factors;
		 
		 //System.out.println(factors);
		 Log.d(TAG,factors.toString());
	 }

	 void calculateRange() throws Exception
	 {
		 for(Double item : factors)
		 {
			 avg += item;
			 
			 if(upperThreshold <= item) upperThreshold = item;
			 if(lowerThreshold >= item) lowerThreshold = item; 
		 }
		 
		 avg /= totalLines;
		 
		 upperThreshold = (upperThreshold*THRESH_FAC + avg)/(THRESH_FAC+1);
		 lowerThreshold = (lowerThreshold*THRESH_FAC + avg)/(THRESH_FAC+1);
		 Log.d(TAG,"lowerThreshold:"+lowerThreshold+" upperThreshold:"+upperThreshold+ " avg:"+avg);
		 
		 boolean meetUpperThreshold = false;
		 boolean meetLowerThreshold = false;
		 int i,j=0;
		 
		 
		 for( i = 0 ; i < totalLines -1;)
		 {
			 if(factors.get(i) >= lowerThreshold )
			 {
				 meetLowerThreshold = true;
				 for( j = i; j < totalLines;)
				 {
					 if(factors.get(j) >= upperThreshold) {
						 meetUpperThreshold = true;
					 }
					 
					 if(factors.get(j) >= lowerThreshold) {						 
						 j++;
					 }
					 else
					 {
						 break;
					 }
				 }
				 
				 if(meetUpperThreshold)
				 {
					 
					 lowerBound = i;
					 upperBound = j-1;
					 Log.d(TAG,"lowerBound:"+lowerBound+" upperBound:"+upperBound);
					 break;
				 }
				 else
				 {
					 i=j;
				 }
			 }
			 else
			 {
				 i++;
			 }
		 }
		 
		 if(!meetLowerThreshold || !meetUpperThreshold)
		 {
			 throw new Exception("invalid web page");
		 }
		 
	 }

	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String uri = "http://www.guardian.co.uk/world/2010/dec/15/clay-duke-bay-district-shooting";
		//Crawler crawler = new Crawler(uri);
		try {
			
		     ContentReader reader = new ContentReader(uri);
		     System.out.println(reader.getResult());
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}

}
